#include "OpengDrawTriangle.h"
#include <QOpenGLVertexArrayObject>

static constexpr const char* vertexShaderText =
"attribute highp vec4 posAttr;\n"
"attribute lowp vec4 colAttr;\n"
"varying lowp vec4 col;\n"
"void main() {\n"
"   col = colAttr;\n"
"   gl_Position = posAttr;\n"
"}\n";

static constexpr const char* fragmentShaderText =
"varying lowp vec4 col;\n"
"void main() {\n"
"   gl_FragColor = col;\n"
"}\n";

OpengDrawTriangle::OpengDrawTriangle()
{
	
}

QString OpengDrawTriangle::createPluginMenu()
{
	return tr("opengl/drawTriangle");
}

void OpengDrawTriangle::createPluginMenuResult(bool result, QString menuId, QString error)
{
	// TODO
}

QWidget* OpengDrawTriangle::createPluginWidget()
{
	if (m_glWidget == nullptr)
	{
		m_glWidget = new OpenglWidget();
		m_glWidget->setAttribute(Qt::WA_NativeWindow);
	}
	return m_glWidget;
}

void OpengDrawTriangle::destroyPluginWidget()
{
	if (m_glWidget)
	{
		delete m_glWidget;
        m_glWidget = nullptr;
	}
}

QOpenGLVertexArrayObject vao1;
QOpenGLVertexArrayObject vao2;
void OpenglWidget::initializeGL()
{
	vao1.create();
	vao2.create();
	QVector<QVector3D> vertexData1 = {
		QVector3D(-0.5, 1, 0),
		QVector3D(1, 1, 0),
		QVector3D(1, -1, 0),
		QVector3D(-0.5, -1, 0)
	};

	QVector<QVector3D> vertexData2 = {
		QVector3D(0 , 0.5,0),
		QVector3D(-0.5 ,-0.5,0),
		QVector3D(0.5 ,-0.5,0),
	};

	QVector<QVector3D> clrData1 = {
		QVector3D(1 , 0, 0),
		QVector3D(1 , 0, 0),
		QVector3D(1 , 0, 0),
		QVector3D(1 , 0, 0),
	};

	QVector<QVector3D> clrData2 = {
		QVector3D(1 , 1, 0),
		QVector3D(1 , 1, 0),
		QVector3D(1 , 1, 0),
	};

	initializeOpenGLFunctions();
	if (!m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderText))
	{
		Q_ASSERT(false);
	}
	if (!m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderText))
	{
		Q_ASSERT(false);
	}
	m_program.link();
	
	int posAttri = m_program.attributeLocation("posAttr");
	int clrAttri = m_program.attributeLocation("colAttr");

	vao1.bind();
	{
		GLuint vbo1;
		GLuint vbo2;
		glGenBuffers(1, &vbo1);
		glGenBuffers(1, &vbo2);

		glBindBuffer(GL_ARRAY_BUFFER, vbo1);
		glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertexData1.size() * 3, vertexData1.constData(), GL_STATIC_DRAW);
		m_program.enableAttributeArray(posAttri);
		m_program.setAttributeBuffer(posAttri, GL_FLOAT, 0, 3);

		glBindBuffer(GL_ARRAY_BUFFER, vbo2);
		glBufferData(GL_ARRAY_BUFFER, sizeof(float) * clrData1.size() * 3, clrData1.constData(), GL_STATIC_DRAW);
		m_program.enableAttributeArray(clrAttri);
		m_program.setAttributeBuffer(clrAttri, GL_FLOAT, 0, 3);

		glBindBuffer(GL_ARRAY_BUFFER, 0);
	}

	vao2.bind();
	{
		GLuint vbo1;
		GLuint vbo2;
		glGenBuffers(1, &vbo1);
		glGenBuffers(1, &vbo2);

		glBindBuffer(GL_ARRAY_BUFFER, vbo1);
		glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertexData2.size() * 3, vertexData2.constData(), GL_STATIC_DRAW);
		m_program.enableAttributeArray(posAttri);
		m_program.setAttributeBuffer(posAttri, GL_FLOAT, 0, 3);

		glBindBuffer(GL_ARRAY_BUFFER, vbo2);
		glBufferData(GL_ARRAY_BUFFER, sizeof(float) * clrData2.size() * 3, clrData2.constData(), GL_STATIC_DRAW);
		m_program.enableAttributeArray(clrAttri);
		m_program.setAttributeBuffer(clrAttri, GL_FLOAT, 0, 3);

		glBindBuffer(GL_ARRAY_BUFFER, 0);
	}


	m_program.release();

}

void OpenglWidget::resizeGL(int w, int h)
{
	glViewport(0, 0, w, h);
}

void OpenglWidget::paintGL()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glDisable(GL_DEPTH_TEST);
	glClearColor(1, 1, 1, 1);

	m_program.bind();

	vao1.bind();
	glDrawArrays(GL_POLYGON, 0, 4);
	vao2.bind();
	glDrawArrays(GL_TRIANGLES, 0, 3);

	m_program.release();
}
